<?php
/**
 * 调试输出
 * @param unknown $data
 */
function print_data($k1=null, $k2=null, $k3=null, $k4=null, $k5=null)
{
    header("Content-type: text/html; charset=utf-8");
    echo "<pre>";
    print_r($k1);echo "<hr>";
    print_r($k2);echo "<hr>";
    print_r($k3);echo "<hr>";
    print_r($k4);echo "<hr>";
    print_r($k5);
    exit();
}
/**
 * 调试输出
 * @param unknown $data
 */
function dump_data($k1=null, $k2=null, $k3=null, $k4=null, $k5=null)
{
    header("Content-type: text/html; charset=utf-8");
    echo "<pre>";
    var_dump($k1);echo "<hr>";
    var_dump($k2);echo "<hr>";
    var_dump($k3);echo "<hr>";
    var_dump($k4);echo "<hr>";
    var_dump($k5);
    exit();
}
/**
 * 系统加密方法
 * @param string $data 要加密的字符串
 * @param string $key 密钥
 * @param int $expire 过期时间（秒）
 * @return string
 */
function think_encrypt($data, $key = '', $expire = 0){
    $key        = md5(empty($key) ? config('system.pass_salt') : $key);
    $data       = base64_encode($data);
    $data_len   = strlen($data);
    $key_len    = strlen($key);
    $char       = '';
    for ($i = 0; $i < $data_len; $i++){
        $char .= substr($key, $i%$key_len, 1);
    }
    $str = sprintf('%010d', $expire ? $expire + time() : 0);
    for ($i = 0; $i < $data_len; $i++){
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1))) % 256);
    }
    $str = str_replace(array('+', '/', '='), array('-', '_', ''), base64_encode($str));
    return strtoupper(md5($str)) . $str;
}
/**
 * 系统解密方法
 * @param string $data 要解密的字符串
 * @param string $key 密钥
 * @return string
 */
function think_decrypt($data, $key = ''){
    $key   = md5(empty($key) ? config('system.pass_salt') : $key);
    $data  = substr($data, 32);
    $data  = str_replace(array('-', '_'), array('+', '/'), $data);
    $mod4  = strlen($data) % 4;
    if ($mod4) {
        $data .= substr('====', $mod4);
    }
    $data   = base64_decode($data);
    $expire = substr($data, 0, 10);
    $data   = substr($data, 10);
    if ($expire > 0 && $expire < time()){
        return '';
    }
    $x          = 0;
    $data_len   = strlen($data);
    $key_len    = strlen($key);
    $char       = $str = '';
    for ($i = 0; $i < $data_len; $i++){
        $char .= substr($key, $i%$key_len, 1);
    }
    for($i = 0; $i < $data_len; $i++) {
        $ch_asc = ord(substr($data, $i, 1)) - ord(substr($char, $i, 1)) + 256;
        $str .= chr($ch_asc%256);
    }
    return base64_decode($str);
}
/**
 * 对数据库保存的密码明文进行加密
 * @param string $password 密码明文
 * @param int $create_time  用户创建时间戳。
 * 用户密码加密
 */
function encrypt_pass($password, $create_time){
    if(empty($password)){
        return '';
    }
    $salt = config('app.pass_salt');
    return md5((string)$create_time.sha1($password).$salt);
}
/**
 * curl请求
 * @param $url string 请求地址
 * @param $param array GET请求参数
 * @param mixed $data POST请求参数
 * @param string $method 请求方式
 * @return mixed|string 请求结果
 */
function HttpRequest($url, $param, $data = '', $method = 'GET'){
    $opts = array(
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
        CURLOPT_URL            => $url
    );
    if(isset($param['set_header'])){
        $opts[CURLOPT_HEADER] = 1;
        unset($param['set_header']);
    }
    if(isset($param['set_http_version'])){
        $opts[CURLOPT_HTTP_VERSION] = CURL_HTTP_VERSION_1_1;
        unset($param['set_http_version']);
    }
    /* 根据请求类型设置特定参数 */
    if(!empty($param)){
        $opts[CURLOPT_URL] .= '?' . http_build_query($param);
    }

    if(strtoupper($method) == 'POST'){
        $opts[CURLOPT_POST] = 1;
        $opts[CURLOPT_POSTFIELDS] = $data;

        if(is_string($data)){ //发送JSON数据
            $opts[CURLOPT_HTTPHEADER] = array(
                'Content-Type: application/json; charset=utf-8',
                'Content-Length: ' . strlen($data),
            );
        }
    }
    /* 初始化并执行curl请求 */
    $ch = curl_init();
    curl_setopt_array($ch, $opts);
    $data  = curl_exec($ch);
    $error = curl_error($ch);
    curl_close($ch);
    //发生错误，抛出异常
    if($error)
    {
        throw new \app\MyException(20000,'请求发生错误：'.$error);
    };
    return  $data;
}
/**
 * 数组去重
 * @param $arr array 原数组
 * @param $key string 判断的key值
 * @return mixed|string 请求结果
 */
function array_unset($arr,$key){
    //建立一个目标数组
    $res = array();
    foreach ($arr as $value) {
        //查看有没有重复项
        if(isset($res[$value[$key]])){
            unset($value[$key]);  //有：销毁
        }else{
            $res[$value[$key]] = $value;
        }
    }
    return $res;
}
/**
 * 数组去重
 * @param $arr array 原数组
 * @param $key string 判断的key值
 * @return mixed|string 请求结果
 */
function array_unset_keys($data, $res, $args){
    $list = [];
    $flag = '';
    foreach ($data as $key => $val) {
        foreach ($res as $k => $v) {
            $tmpStr = implode(',', $v);
            if ($key == 0 && $k == 0) {
                $flag .= $tmpStr;
                $list[] = $data[$key];
            }
            if (handle_arguments($val, $v, $args) && strpos($flag, $tmpStr) === false) {
                $flag .= '|'.$tmpStr;
                $list[] = $data[$key];
            }
        }
    }
    return $list;
}

function handle_arguments($val, $value, $args) {
    foreach ($args as $k => $v) {
        if ($val[$v] != $value[$v]) {
            return false;
        }
    }
    return true;
}

//随机产生六位数密码
function randStr($len=6,$format='ALL') {
    switch($format) {
        case 'ALL':
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-@#~';
            break;
        case 'CHAR':
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-@#~';
            break;
        case 'NUMBER':
            $chars='0123456789';
            break;
        default :
            $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-@#~';
            break;
    }
    mt_srand((double)microtime()*1000000*getmypid());
    $password="";
    while(strlen($password)<$len)
        $password.=substr($chars,(mt_rand()%strlen($chars)),1);
    return $password;
}

/**
 * 请求正确返回
 * @param array $data
 * @param int $code
 * @param string $msg
 * @return \think\response\Json
 */
function json_ok($data=[], $code=0, $message='', $status_code=200){
    $return_data = [
        "data"     => $data,
        "code"     => $code,
        "message"  => !empty($message)?$message:(isset(config('error')[$code]) ? config('error')[$code] : '')
    ];
    return json($return_data,$status_code);
}

/**
 * 请求错误返回
 * @param int $code
 * @param string $msg
 * @return \think\response\Json
 */
function json_error($code = 1, $message = '', $status = 200)
{
    if ($message == '') {
        $result['message'] = isset(config('error')[$code]) ? config('error')[$code] : '';
    } else {
        $result['message'] = $message;
    }
    $result['status'] = $status;
    $result['code']   = $code;
    return json($result);
}

/**
 * 判断数据是否为空并且转数组
 * @param $data
 */
function ObjectToArray($data){
    if(empty($data) || $data->isEmpty()){
        return [];
    }else{
        return $data->toArray();
    }
}
/**
 * 与go程序交互签名
 * @param $param  参数
 * @param $key 秘钥
 */
function createSign($param, $key){
    ksort($param);
    $factor = '';
    foreach ($param as $k=>$v){
        $factor .= $k.$v;
    }
    return strtoupper(bin2hex(hash_hmac("sha1", $factor, $key, true)));
}

/**
 * 获取客户端IP地址
 * @return array|false|string
 */
function get_ip(){
    if(@$_SERVER["HTTP_X_FORWARDED_FOR"])
        $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
    else if(@$_SERVER["HTTP_CLIENT_IP"])
        $ip = $_SERVER["HTTP_CLIENT_IP"];
    else if(@$_SERVER["REMOTE_ADDR"])
        $ip = $_SERVER["REMOTE_ADDR"];
    else if(@getenv("HTTP_X_FORWARDED_FOR"))
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if(@getenv("HTTP_CLIENT_IP"))
        $ip = getenv("HTTP_CLIENT_IP");
    else if(@getenv("REMOTE_ADDR"))
        $ip = getenv("REMOTE_ADDR");
    else
        $ip = "Unknown";
    return $ip;
}

/**
 * 检测手机号格式
 * @param $mobile
 * @return false|int
 */
function check_mobile($mobile){
    return preg_match('/^1[3|4|5|6|7|8|9]\d{9}$/',$mobile);
}

/**
 * @todo 程序内结果返回格式(用于不同类的方法调用、外部接口返回结果传递等)
 * @author ZJF
 * @param $data array/string 返回数据
 * @param $code int 0:成功，大于0:失败
 * @param $message string 描述
 * @return array
 */
function array_response($data = [],$code=0,$message='成功'){
    $response = array(
        'code'=>$code,
        'message'=>$message,
        'data'=>$data
    );
    return $response;
}

/** @todo 把网络图片图片转成base64
 * @param string $img 图片地址
 * @return string
 */
function imgtobase64($img_url='')
{
    if(empty($img_url)){
        return '';
    }
    try{
        $imageInfo = getimagesize($img_url);
    }catch (\Exception $e){
        return '';
    }
    return 'data:' . $imageInfo['mime'] . ';base64,' . chunk_split(base64_encode(file_get_contents($img_url)));
}

/**
 * @todo 手机号验证
 * @author ZJF
 */
function checkPhone($phone=''){
    if(!preg_match('/^(?:(?:\+|00)86)?1[3-9]\d{9}$/',$phone)){
        return false;
    }
    return true;
}